Android 中选择一张图片然后截取部分作为头像是一个非常常见的需求。当然很多个性化的应用中都会有自己专门定制的选择图片和裁剪图片。但本文现在主要讨论的是一些系统的东西,包括打开系统图片的选择、调用系统的截图功能。
以前在调用系统的截图的时候我都是这样使用的。
|
|
这样写好像真的很简单也很好懂,Intent.ACTION_PICK 打开选择图片的界面,然后通过下面的intent 的一些设置就可以截取一张图片了。这样写在我的很多的机器上确实也没有什么问题,但是直到碰到了5.0 的手机。在5.0 的手机中,首先出现的一个问题是,上面的代码没有出现图片的裁剪功能。流程变成了选择图片,点击图片以后就选择了整张的图片。选择一整张图片确实是没问题,但是需求是必须给用户一个截取图片的过程(其实选取一整张图片还是有一个很严重的问题的,就是图片太大的问题)。
经过分析,这个的问题是在5.0 的手机中,只执行了一个选择图片的过程。或许应该将图片的选择和图片的截取分开才能完成自己的需求。
第一步:如何打开图片的选择界面。
1.Intent.ACTION_PICK = "android.intent.action.PICK";
选择一个数据返回它的URI。返回的格式:content://media/external/images/media/67
。在所有的版本中都是返回这样的格式。
2.Intent.ACTION_GET_CONTENT = "android.intent.action.GET_CONTENT";
选择一个数据。
API 19及以上,返回的Uri:content://com.android.providers.media.documents/document/image%3A57425
API 19以下,返回的Uri:content://media/external/images/media/31956
在API 19中又可以从下载内容(其实在API 19及以上从很多不同的地方拿到的Uri不相同)中打开一些内容,Uri是这样的类型。content://com.android.providers.downloads.documents/document/4
3.Intent.ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
(API 19以后才有这个),可以打开云端的文件。只有在API 19以上才可以使用,得到的Uri跟API 19在Intent.ACTION_GET_CONTENT
中得到的一样。
所以第一步可以有三种选择来打开一个选择图片的界面。根据我们的需求应该选择ACTION_PICK 来做,因为只有这个可以兼容所有的版本。(当然使用ACTION_GET_CONTENT 和ACTION_OPEN_DOCUMENT 也是可以做的,但是区分其实蛮大的)
使用ACTION_PICK,打开图片选择的过程。
|
|
在选中一张图片以后就会在onActivityResult中得到一张图片的Uri。然后就需要打开这张图片并裁剪。
第二步.如何的截取图片。
系统的截图 com.android.camera.action.CROP
。
|
|
这样就可以在onActivityResult 方法中做相关的处理。Bitmap bitmap = data.getParcelableExtra("data");
其实只有基于AOSP 的Android 手机才会具有com.android.camera.action.CROP
,所以需要做相应的异常的处理。所以需要加一个ActivityNotFoundException
的异常的处理。
|
|
这样在很多机器上测试的时候都没有问题,但是这样就结束了吗?还没有。当图片很大的时候,这样还是会出现问题,一整张图片可能直接会使内存溢出,或者说裁剪的一张图片会使内存溢出(特别是对手机像素很高的来说)。所有呢,最好的情况是对图片进行压缩。
|
|
所以呢可以专门写一个用来压缩的函数。(我这里是指定大小为300,300)
|
|